package com.jk.common.response;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jk.common.enums.WitmoreErrorCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

/**
 * Description: 自定义响应类
 * Author: 豆子高
 * Date: 2025/2/24 11:55
 */
@Schema(name = "ResponsePageResult", description = "分页响应类")
@Data
public class ResponsePageResult<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    @Schema(description = "状态码")
    private int code;

    /**
     * 消息
     */
    @Schema(description = "消息")
    private String message;

    /**
     * 返回的数据
     */
    @Schema(description = "返回的数据")
    private List<T> records;

    /**
     * 时间戳
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "时间戳")
    private LocalDateTime timestamp;

    /**
     * 分页信息
     */
    @Schema(description = "分页信息")
    private PageInfo page;

    public ResponsePageResult(int code, String message, List<T> records, PageInfo page) {
        this.code = code;
        this.message = message;
        this.records = records;
        this.page = page;
        this.timestamp = LocalDateTime.now();
    }

    public ResponsePageResult() {

    }

    /**
     * 成功响应（无数据）
     */
    public static <T> ResponsePageResult<T> success(PageInfo page) {

        return success(null, page);
    }

    /**
     * 成功响应（带数据）
     */
    public static <T> ResponsePageResult<T> success(List<T> records, PageInfo page) {
        ResponsePageResult<T> response = new ResponsePageResult<>();
        response.setCode(WitmoreErrorCode.SUCCESS.getCode());
        response.setMessage("success");
        response.setRecords(records);
        response.setPage(page);
        response.setTimestamp(LocalDateTime.now());
        return response;
    }

    public static <T, R> ResponsePageResult<R> success(Page<T> page, ToVo<T, R> toVo) {
        List<R> result = page.getRecords().stream()
                .map(toVo::to)
                .toList();
        return success(result, new PageInfo(page.getCurrent(), page.getSize(), page.getTotal(), page.getPages()));
    }

    public static <T> ResponsePageResult<T> success(Page<T> page) {
        return success(page.getRecords(), new PageInfo(page.getCurrent(), page.getSize(), page.getTotal(), page.getPages()));
    }


    /**
     * 失败响应
     */
    public static <T> ResponsePageResult<T> fail(int code, String message) {
        ResponsePageResult<T> response = new ResponsePageResult<>();
        response.setCode(code);
        response.setMessage(message);
        response.setTimestamp(LocalDateTime.now());
        return response;
    }

    public static <T> ResponsePageResult<T> fail(WitmoreErrorCode errorCode) {
        ResponsePageResult<T> response = new ResponsePageResult<>();
        response.setCode(errorCode.getCode());
        response.setMessage(errorCode.getMessage());
        response.setTimestamp(LocalDateTime.now());
        return response;
    }

    @FunctionalInterface
    public interface ToVo<T, R> {
        R to(T t);
    }

}